package main

import "fmt"

func main() {
	/*
		1.空接口(interface{})
			不包含任何的方法，正因为如此，所有的类型都实现了空接口，因此空接口可以存储任意类型的数值。
			eg: fmt 包下的 Print 系列函数：
					func Print(a ...any) (n int, err error)
					func Printf(format string, a ...any) (n int, err error)
					func Println(a ...any) (n int, err error)

		2.空接口的用途：
		（1）泛型：弥补没有泛型的一种手段
		（2）反射：空接口是实现反射的基础

		3.空接口和 nil：
			空接口不是真的空,空接口有两个字段：
				(1)实例类型
				(2)指向绑定实例的指针
		      	只有二者都为 nil 时，空接口才为 nil
	*/
	var a1 A = Dog{"Tom"}
	var a2 A = Person9{"Jerry", 6}
	var a3 A = "xixi"
	var a4 A = 100
	fmt.Println(a1) //{Tom}
	fmt.Println(a2) //{Jerry 6}
	fmt.Println(a3) //xixi
	fmt.Println(a4) //100
	test1(a1)
	test1(a3)
	test1(3.14)
	test1("喜羊羊")

	test2(a2)
	test2(a4)

	//map：key字符串，value任意类型
	map1 := make(map[string]interface{})
	map1["name"] = "Jerry"
	map1["age"] = 6
	map1["friend"] = Person9{"Tom", 8}
	fmt.Println(map1)

	//切片，存储任意类型的数据
	slice1 := make([]interface{}, 0, 10)
	slice1 = append(slice1, a1, a2, a3, a4, 100, "abc")
	fmt.Println(slice1)

	test3(slice1)
}

func test3(slice2 []interface{}) {
	for i := 0; i < len(slice2); i++ {
		fmt.Printf("第 %d 个数据：%v\n", i, slice2[i])
	}
}

// 接口A是空接口，理解为代表了任意类型
func test1(a A) {
	fmt.Println(a)
}

func test2(a interface{}) {
	fmt.Println(a)
}

// 空接口
type A interface {
}
type Dog struct {
	color string
}
type Person9 struct {
	name string
	age  int
}
